<template>
  <div class="math-panel">
    <!-- 顶部导航栏 -->
    <header class="math-header">
      <div class="header-content">
        <h3>🧮 现代数学解题模型</h3>
        <div class="header-actions">
          <button class="btn help-btn" @click="showHelp">
            <span>帮助</span>
            <i class="icon-question">?</i>
          </button>
        </div>
      </div>
    </header>

    <!-- 主内容区 -->
    <main class="math-main">
      <!-- 左侧对话区 -->
      <section class="chat-section">
        <!-- 对话消息容器 -->
        <div class="messages-wrapper" ref="messagesContainer">
          <!-- 空状态提示 -->
          <div v-if="chatMessages.length === 0 && !solving" class="empty-state">
            <div class="empty-icon">📝</div>
            <p>请输入数学问题，AI 将为您逐步解答</p>
            <p class="empty-hint">支持方程求解、积分计算、动力系统分析等</p>
          </div>

          <!-- 对话消息列表 -->
          <div class="messages-list">
            <div 
              v-for="(message, index) in chatMessages" 
              :key="index"
              :class="['message-item', `message-${message.role}`]"
            >
              <div class="message-avatar">
                {{ message.role === 'user' ? '你' : 'AI' }}
              </div>
              <div class="message-bubble">
                <MarkdownRenderer :content="message.content" />
              </div>
            </div>

            <!-- 加载状态 -->
            <div v-if="solving" class="loading-indicator">
              <div class="spinner"></div>
              <p>AI 正在解题，请稍候...</p>
            </div>
          </div>

          <!-- 滚动锚点 -->
          <div ref="scrollAnchor" class="scroll-anchor"></div>
        </div>

        <!-- 输入区域（固定在底部） -->
        <div class="input-section">
          <div class="input-wrapper">
            <textarea
              v-model="mathInput"
              placeholder="请输入数学问题，例如：求解方程 x² + 2x - 3 = 0 或 计算定积分 ∫₀¹ x² dx"
              :disabled="solving"
              @keydown.enter.exact.prevent="solveProblem"
              :style="{ minHeight: textareaHeight + 'px' }"
              @input="autoAdjustTextarea"
              class="math-input"
            ></textarea>
            
            <div class="input-controls">
              <div class="resize-buttons">
                <button 
                  class="btn resize-btn" 
                  @click="resizeTextarea(-20)" 
                  :disabled="textareaHeight <= 80"
                  :title="textareaHeight <= 80 ? '已达最小高度' : '减小高度'"
                >
                  −
                </button>
                <button 
                  class="btn resize-btn" 
                  @click="resizeTextarea(20)" 
                  :disabled="textareaHeight >= 300"
                  :title="textareaHeight >= 300 ? '已达最大高度' : '增加高度'"
                >
                  +
                </button>
              </div>
              
              <div class="action-buttons">
                <button 
                  class="btn btn-danger" 
                  :disabled="!solving" 
                  @click="abortSolve"
                >
                  中断
                </button>
                <button 
                  class="btn btn-primary" 
                  :disabled="!mathInput.trim() || solving" 
                  @click="solveProblem"
                >
                  {{ solving ? '解题中...' : '发送' }}
                </button>
              </div>
            </div>
          </div>
        </div>
      </section>

      <!-- 右侧预设问题区 -->
      <aside class="preset-section">
        <div class="preset-header">
          <h3>🔖 预设问题</h3>
          <div class="divider"></div>
        </div>
        
        <div class="preset-list">
          <div 
            v-for="(categoryItem, categoryIndex) in presetQuestions" 
            :key="categoryIndex"
            class="preset-category"
          >
            <h4 class="category-title">
              {{ categoryItem.category }}
            </h4>
            
            <div class="questions-group">
              <div 
                v-for="(question, questionIndex) in categoryItem.questions" 
                :key="questionIndex"
                class="question-card"
                @click="selectPresetQuestion(question)"
                @mouseenter="hoveredQuestion = `${categoryIndex}-${questionIndex}`"
                @mouseleave="hoveredQuestion = ''"
                :class="{ 'question-hover': hoveredQuestion === `${categoryIndex}-${questionIndex}` }"
              >
                {{ question }}
              </div>
            </div>
          </div>
        </div>
      </aside>
    </main>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, nextTick, Ref } from 'vue';
import { API_BASE_URL } from '@/config/api';
import MarkdownRenderer from '@/components/MarkdownRender_for_math.vue';
import 'katex/dist/katex.min.css';

// 类型定义
interface ChatMessage {
  role: 'user' | 'ai';
  content: string;
}

interface PresetCategory {
  category: string;
  questions: string[];
}

// 响应式数据
const mathInput = ref('');
const solving = ref(false);
const chatMessages = ref<ChatMessage[]>([]);
const sessionId = ref('');
const abortController: Ref<AbortController | null> = ref(null);
const textareaHeight = ref(120); // 输入框初始高度
const hoveredQuestion = ref(''); // 用于预设问题的hover效果

// DOM引用
const messagesContainer = ref<HTMLElement | null>(null);
const scrollAnchor = ref<HTMLElement | null>(null);

// 预设问题列表
const presetQuestions: PresetCategory[] = [
  {
    category: "1. 连续动力系统（微分方程）",
    questions: [
      "判断动力系统 \\( \\dot{x} = 3x + 4y, \\ \\dot{y} = -4x + 3y \\) 的平衡点类型与稳定性。",
      "求系统 \\( \\dot{x} = y - x^3, \\ \\dot{y} = -x \\) 在原点处的稳定性。",
      "绘制系统 \\( \\dot{x} = y, \\ \\dot{y} = -\\sin x \\) 的相图并分类轨线类型。",
      "分析捕食–被捕食系统 \\( \\dot{x} = x(1 - y), \\ \\dot{y} = -y + xy \\) 是否存在稳定的周期轨道。"
    ]
  },
  {
    category: "2. 离散动力系统（映射）",
    questions: [
      "对离散系统 \\( x_{n+1} = r x_n (1 - x_n) \\)，当 \\( r = 3.2 \\) 时判断固定点的稳定性。",
      "讨论 Logistic 映射 \\( x_{n+1} = 4x_n(1-x_n) \\) 是否呈现混沌行为。"
    ]
  },
  {
    category: "3. 分岔与混沌理论",
    questions: [
      "讨论系统 \\( \\dot{x} = r + x^2 \\) 的分岔类型。",
      "判断系统 \\( \\dot{x} = \\mu x - y - x(x^2 + y^2), \\ \\dot{y} = x + \\mu y - y(x^2 + y^2) \\) 是否发生 Hopf 分岔。",
      "判断 Duffing 振子 \\( \\ddot{x} + 0.2\\dot{x} - x + x^3 = 0.3\\cos(1.2t) \\) 是否可能出现混沌。"
    ]
  },
  {
    category: "4. 特殊模型分析",
    questions: [
      "分析 Lorenz 系统 \\( \\dot{x} = 10(y-x), \\ \\dot{y} = x(28-z)-y, \\ \\dot{z} = xy - \\tfrac{8}{3}z \\) 的平衡点稳定性。",
      "讨论 FitzHugh–Nagumo 模型 \\( \\dot{v} = v - \\tfrac{v^3}{3} - w + I, \\ \\dot{w} = \\varepsilon (v + a - b w) \\) 在参数 \\( I \\) 变化时是否会产生振荡。"
    ]
  }
];

// 输入框高度调整
const resizeTextarea = (delta: number) => {
  textareaHeight.value += delta;
  // 限制高度范围
  textareaHeight.value = Math.max(80, Math.min(300, textareaHeight.value));
};

// 自动调整输入框高度（根据内容）
const autoAdjustTextarea = () => {
  const minHeight = 80;
  const maxHeight = 300;
  const textarea = document.querySelector('.math-input') as HTMLTextAreaElement;
  
  if (textarea) {
    // 临时移除高度限制以计算自然高度
    textarea.style.minHeight = 'auto';
    textarea.style.height = 'auto';
    const scrollHeight = textarea.scrollHeight;
    
    // 应用限制后的高度
    const newHeight = Math.max(minHeight, Math.min(maxHeight, scrollHeight));
    textareaHeight.value = newHeight;
    
    // 恢复样式
    textarea.style.minHeight = `${newHeight}px`;
    textarea.style.height = `${newHeight}px`;
  }
};

// 选择预设问题
const selectPresetQuestion = (question: string) => {
  mathInput.value = question;
  // 自动调整输入框高度以适应内容
  nextTick(autoAdjustTextarea);
};

// 帮助提示
const showHelp = () => {
  chatMessages.value.push({
    role: 'ai',
    content: `### 数学解题模型使用帮助
- 支持输入各类数学问题（方程、积分、动力系统等）
- 可直接输入 LaTeX 公式（如 \$x^2 + y^2 = 1\$）
- 点击右侧预设问题可快速加载示例
- 输入框可通过 +/- 按钮调整高度
- 解题过程中可点击「中断」停止计算`
  });
  scrollToBottom();
};

// 滚动到最新消息
const scrollToBottom = () => {
  nextTick(() => {
    if (scrollAnchor.value) {
      scrollAnchor.value.scrollIntoView({ 
        block: 'end', 
        behavior: 'smooth' 
      });
    }
  });
};

// 组件挂载时初始化会话
onMounted(async () => {
  try {
    // 创建会话
    const response = await fetch(`${API_BASE_URL}/api/sessions`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ module: 'math', title: '数学解题会话' })
    });
    
    if (response.ok) {
      const session = await response.json();
      sessionId.value = session.id;
      
      // 加载历史消息
      const messagesResponse = await fetch(`${API_BASE_URL}/api/sessions/${sessionId.value}?module=math`);
      if (messagesResponse.ok) {
        const messagesData = await messagesResponse.json();
        chatMessages.value = messagesData.messages.map((msg: any) => ({
          role: msg.role as 'user' | 'ai',
          content: msg.content
        }));
        scrollToBottom(); // 加载完成后滚动到底部
      }
    } else {
      throw new Error('创建数学会话失败');
    }
  } catch (error) {
    console.error('会话初始化失败：', error);
    chatMessages.value.push({
      role: 'ai',
      content: `⚠️ 初始化失败：${error instanceof Error ? error.message : '无法连接到服务器'}`
    });
  }
});

// 监听消息变化，自动滚动
watch(chatMessages, () => {
  if (!solving.value) scrollToBottom();
}, { deep: true });

// 解题逻辑
const solveProblem = async () => {
  const question = mathInput.value.trim();
  if (!question || solving.value) return;
  if (!sessionId.value) {
    chatMessages.value.push({
      role: 'ai',
      content: '⚠️ 会话未初始化，请刷新页面重试'
    });
    return;
  }

  // 添加用户消息
  chatMessages.value.push({ role: 'user', content: question });
  mathInput.value = '';
  solving.value = true;
  abortController.value = new AbortController();

  // 添加AI消息占位
  const aiMessageIndex = chatMessages.value.length;
  chatMessages.value.push({ role: 'ai', content: '' });

  try {
    const requestBody = {
      messages: chatMessages.value.map(msg => ({
        role: msg.role,
        content: msg.content
      }))
    };

    const queryParams = new URLSearchParams({
      session_id: sessionId.value,
      model: 'math-model',
      max_input_length: '1024',
      max_new_tokens: '8192',
      temperature: '0.6',
      top_p: '0.95',
      do_sample: 'true'
    });

    const response = await fetch(
      `${API_BASE_URL}/api/math/stream?${queryParams.toString()}`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(requestBody),
        signal: abortController.value.signal
      }
    );

    if (!response.ok) throw new Error(`请求失败: ${response.status}`);
    if (!response.body) throw new Error('未获取到响应内容');

    // 处理流式响应
    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let fullResponse = '';

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      const chunk = decoder.decode(value);
      const lines = chunk.split('\n').filter(line => 
        line.startsWith('data: ') && line.trim() !== 'data: [DONE]'
      );

      for (const line of lines) {
        let content = line.replace('data: ', '');
        if (content) {
          fullResponse += content;
          chatMessages.value[aiMessageIndex].content = fullResponse;
          scrollToBottom(); // 实时滚动
        }
      }
    }

  } catch (error) {
    chatMessages.value[aiMessageIndex].content = `解题失败：${error instanceof Error ? error.message : String(error)}`;
  } finally {
    solving.value = false;
    abortController.value = null;
  }
};

// 中断解题
const abortSolve = () => {
  if (abortController.value) {
    abortController.value.abort();
    solving.value = false;
    
    const lastMessage = chatMessages.value[chatMessages.value.length - 1];
    if (lastMessage && lastMessage.role === 'ai') {
      lastMessage.content += `\n\n⚠️ 解题已中断（会话ID：${sessionId.value.slice(0, 6)}）`;
    }
    abortController.value = null;
  }
};
</script>

<style scoped>
/* 基础样式 */
.math-panel {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: var(--app-bg, #f8fafc);
  color: var(--text-primary, #1e293b);
  overflow: hidden;
}

/* 顶部导航 */
.math-header {
  padding: 0 20px;
  height: 60px;
  background-color: var(--header-bg, #ffffff);
  border-bottom: 1px solid var(--border-light, #e2e8f0);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  z-index: 10;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
}

.math-header h3 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--primary-color, #3b82f6);
}

.header-actions {
  display: flex;
  gap: 12px;
}

.help-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: transparent;
  border: 1px solid var(--border-light, #e2e8f0);
  border-radius: 6px;
  color: var(--text-secondary, #64748b);
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.2s;
}

.help-btn:hover {
  background-color: var(--hover-bg, #f1f5f9);
  border-color: var(--primary-color, #3b82f6);
  color: var(--primary-color, #3b82f6);
}

/* 主内容区 */
.math-main {
  display: flex;
  flex: 1;
  overflow: hidden;
  padding: 16px;
  gap: 16px;
}

/* 对话区域 */
.chat-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0; /* 防止内容溢出 */
}

.messages-wrapper {
  flex: 1;
  background-color: var(--card-bg, #ffffff);
  border-radius: 12px;
  border: 1px solid var(--border-light, #e2e8f0);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* 空状态 */
.empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
  color: var(--text-secondary, #64748b);
  text-align: center;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.7;
}

.empty-hint {
  margin-top: 8px;
  font-size: 0.9rem;
  opacity: 0.8;
}

/* 消息列表 */
.messages-list {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
}

.message-item {
  display: flex;
  margin-bottom: 20px;
  max-width: 85%;
  animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.message-user {
  margin-left: auto;
  flex-direction: row-reverse;
}

.message-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.9rem;
  margin-top: 4px;
}

.message-user .message-avatar {
  background-color: var(--primary-color, #3b82f6);
  color: white;
}

.message-ai .message-avatar {
  background-color: var(--secondary-color, #64748b);
  color: white;
}

.message-bubble {
  line-height: 1.5;
}


.message-user .message-bubble {
  background-color: var(--primary-light, #eff6ff);
  border: 1px solid var(--primary-border, #dbeafe);
  margin-right: 12px;
}

.message-ai .message-bubble {
  background-color: var(--ai-bg, #f8fafc);
  border: 1px solid var(--border-light, #e2e8f0);
  margin-left: 12px;
}

/* 加载状态 */
.loading-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  color: var(--text-secondary, #64748b);
  gap: 12px;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid var(--border-light, #e2e8f0);
  border-top-color: var(--primary-color, #3b82f6);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 输入区域 */
.input-section {
  background-color: var(--card-bg, #ffffff);
  border-radius: 12px;
  border: 1px solid var(--border-light, #e2e8f0);
  padding: 16px;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.03);
  margin-bottom: 20px; /* ← 加这个 */
}

.input-wrapper {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  align-items: stretch; /* 高度和输入框一致 */
  margin-bottom: 100px; /* ← 加这个 */
}

.math-input {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid var(--border-light, #e2e8f0);
  border-radius: 8px;
  resize: none;
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color 0.2s;
  background-color: var(--input-bg, #ffffff);
  color: var(--text-primary, #1e293b);
}

.math-input:focus {
  outline: none;
  border-color: var(--primary-color, #3b82f6);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

.math-input:disabled {
  background-color: var(--disabled-bg, #f1f5f9);
  cursor: not-allowed;
  opacity: 0.8;
}

.input-controls {
  display: flex;
  flex-direction: row; /* 按钮组上下排列 */
  gap: 4px;
}

.resize-buttons {
  display: flex;
  flex-direction: column;
  justify-content: space-between; /* 上下对齐 */
  gap: 4px;
}

.resize-btn {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1px solid var(--border-light, #e2e8f0);
  background-color: var(--btn-bg, #f8fafc);
  color: var(--text-secondary, #64748b);
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.2s;
}

.resize-btn:hover:not(:disabled) {
  background-color: var(--primary-light, #eff6ff);
  border-color: var(--primary-color, #3b82f6);
  color: var(--primary-color, #3b82f6);
}

.resize-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-buttons {
  flex-direction: column;
  display: flex;
  justify-content: space-between; /* 上下对齐 */
  gap: 4px;
}

.btn {
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid transparent;
}

.btn-primary {
  background-color: var(--primary-color, #3b82f6);
  color: white;
  border-color: var(--primary-color, #3b82f6);
}

.btn-primary:hover:not(:disabled) {
  background-color: var(--primary-dark, #2563eb);
}

.btn-primary:disabled {
  background-color: var(--primary-disabled, #93c5fd);
  cursor: not-allowed;
}

.btn-danger {
  background-color: var(--danger-light, #fee2e2);
  color: var(--danger-color, #dc2626);
  border-color: var(--danger-border, #fecaca);
}

.btn-danger:hover:not(:disabled) {
  background-color: var(--danger-hover, #fecaca);
}

.btn-danger:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 预设问题区域 */
.preset-section {
  width: 340px;
  background-color: var(--card-bg, #ffffff);
  border-radius: 12px;
  border: 1px solid var(--border-light, #e2e8f0);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.preset-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-light, #e2e8f0);
}

.preset-header h3 {
  margin: 0;
  font-size: 1.1rem;
  color: var(--text-primary, #1e293b);
}

.divider {
  height: 1px;
  background-color: var(--border-light, #e2e8f0);
  margin-top: 12px;
}

.preset-list {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}

.preset-category {
  margin-bottom: 24px;
}

.category-title {
  margin: 0 0 12px 0;
  font-size: 0.95rem;
  color: var(--primary-color, #3b82f6);
  font-weight: 600;
  padding-left: 8px;
  border-left: 3px solid var(--primary-color, #3b82f6);
}

.questions-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.question-card {
  padding: 12px 14px;
  border-radius: 8px;
  border: 1px solid var(--border-light, #e2e8f0);
  background-color: var(--question-bg, #f8fafc);
  font-size: 0.9rem;
  line-height: 1.5;
  cursor: pointer;
  transition: all 0.2s;
  color: var(--text-primary, #1e293b);
}

.question-hover {
  border-color: var(--primary-color, #3b82f6);
  background-color: var(--primary-lightest, #f0f9ff);
  transform: translateY(-1px);
  box-shadow: 0 2px 5px rgba(59, 130, 246, 0.05);
}

/* 滚动锚点（用于精确滚动到底部） */
.scroll-anchor {
  height: 1px;
}

/* 响应式适配 */
@media (max-width: 1024px) {
  .math-main {
    padding: 12px;
  }
  
  .preset-section {
    width: 280px;
  }
}

@media (max-width: 768px) {
  .math-main {
    flex-direction: column;
  }
  
  .preset-section {
    width: 100%;
    max-height: 240px;
  }
  
  .message-item {
    max-width: 90%;
  }
}
</style>